package com.ruoyi.zyc;

import java.time.LocalDate;
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class Java8 {

    public static void main(String[] args) {
//        sort();
//        filter();
//        sum();
        optional();
    }

    /**
     * Java 8中的Stream API提供了一种简洁、功能强大的方式来处理集合数据。通过Stream API，您可以使用各种操作来过滤、映射、排序等处理集合元素。以下是一些常见的Java 8 Stream使用方式和功能：
     * <p>
     * 创建Stream：您可以使用集合对象的stream()方法来创建一个Stream。例如，通过list.stream()将一个List转换为Stream。
     * <p>
     * 过滤操作：使用filter()方法来筛选出符合特定条件的元素。例如，以下代码过滤出列表中所有的偶数：
     */

    public static void stream() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
//        List<Integer> evenNumbers = numbers.stream()
//                .filter(number -> number % 2 == 0)
//                .collect(Collectors.toList());


//映射操作：使用map()方法将每个元素转换为另一种类型的值。例如，以下代码将一个字符串列表转换为大写字母列表：
//        List<String> strings = Arrays.asList("Java", "Python", "C++");
//        List<String> uppercaseStrings = strings.stream()
//                .map(String::toUpperCase)
//                .collect(Collectors.toList());
//排序操作：使用sorted()方法对元素进行排序。例如，以下代码将一个整数列表按升序排序：
//        List<Integer> numbers1 = Arrays.asList(4, 2, 7, 1, 5);
//        List<Integer> sortedNumbers = numbers1.stream()
//                .sorted()
//                .collect(Collectors.toList());
//收集操作：使用collect()方法将Stream转换回集合类型。例如，以下代码将Stream中的元素收集到一个列表中：
//        List<String> result = strings.stream()
//                .map(String::toLowerCase)
//                .collect(Collectors.toList());
        /*中间操作：除了以上提到的终端操作外，Stream API还提供了一些中间操作，允许您在Stream上进行多次操作。例如，forEach()方法允许您对每个元素执行自定义操作，limit()方法限制了Stream中元素的数量。
延迟计算：通过使用lazy()方法，您可以实现延迟计算，即只有在需要时才处理Stream中的元素。这有助于节省资源并提高性能。
并行处理：通过使用parallel()方法，您可以将Stream拆分为多个子任务，并在多个线程上并行处理它们。这可以提高处理大数据集时的性能。但请注意，并行处理可能导致结果顺序不确定。
方法引用：使用方法引用来简化代码。例如，String::toUpperCase是toUpperCase()方法的引用。方法引用使代码更简洁、易读。*/

// 过滤出偶数并打印
        numbers.stream()
                .filter(number -> number % 2 == 0)
                .forEach(System.out::println);

// 将整数列表转换为字符串列表并打印
//        List<String> strings1 = numbers.stream()
//                .map(String::valueOf)
//                .collect(Collectors.toList());
//        strings.forEach(System.out::println);

// 计算整数列表的总和并打印
        int sum = numbers.stream()
                .reduce(0, Integer::sum);
        System.out.println("Sum: " + sum);
    }

    /*方法引用：方法引用是Lambda表达式的另一种形式，它允许您引用现有方法而不是编写Lambda表达式。方法引用的基本语法如下：*/
    public static void methos() {
        List<String> names = Arrays.asList("John", "Mary", "Bob");
        names.forEach(System.out::println);
    }

    /*使用Lambda表达式对列表进行排序*/
    public static void sort() {
        List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2);
        numbers.sort((Integer a, Integer b) -> a.compareTo(b));
        System.out.println(numbers);
    }

    /*使用方法引用对列表进行过滤*/
    public static void filter() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> evenNumbers = numbers.stream()
                .filter(n -> n % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(evenNumbers);
    }

    /*使用Stream API对列表进行转换和求和*/
    public static void sum() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        int sum = numbers.stream()
                .map(n -> n * n) // 将每个数字的平方映射为新的流
                .reduce(0, Integer::sum); // 将流中的数字求和
        System.out.println(sum);
    }

    /*流(Stream)API：Java SE 8引入了流API，它允许您以声明方式处理数据集合。使用流API，您可以轻松地对集合进行过滤、映射、排序等操作。下面是一个使用流API的例子：*/
    public static void sum1() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        int sum = numbers.stream().mapToInt(Integer::intValue).sum();
        System.out.println("Sum: " + sum);
    }

    /*Optional类：Java SE 8引入了Optional类，它允许您更优雅地处理空指针异常。使用Optional类，您可以避免在代码中频繁地进行null检查。下面是一个使用Optional类的例子：*/
    public static void optional() {
        List<Integer> numbers = null;
        Optional<List<Integer>> optional = Optional.ofNullable(numbers);
        optional.ifPresent(System.out::println);
    }

    /**
     * LocalDate 是 Java 8 引入的一个类，用于处理日期，不包含时间。这个类在 java.time 包中，它表示的是日期，年月日，
     * 没有时间的部分。使用它可以避免很多日期处理时的陷阱，比 Date 和 Calendar 类更安全，更易于使用
     */
    public static void localdate() {
//        获取当前日期
        LocalDate date = LocalDate.now();
        System.out.println("Today's date: " + date);
//        获取指定年月的日期
        LocalDate date1 = LocalDate.of(2023, Month.JUNE, 24);
        System.out.println(date1);
//        日期增加
        LocalDate tomorrow = date.plusDays(1); // 日期加一天
        LocalDate nextMonth = date.plusMonths(1); // 日期加一个月
        LocalDate yesterday = date.minusDays(1); // 日期减一天
        LocalDate lastMonth = date.minusMonths(1); // 日期减一个月
        boolean isLeapYear = date.isLeapYear(); // 是否是闰年
        boolean isAfter = date.isAfter(LocalDate.now()); // 是否在当前日期之后
        boolean isBefore = date.isBefore(LocalDate.now()); // 是否在当前日期之前
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String formattedDate = date.format(formatter); // 格式化日期为字符串 "2023-06-24"
    }

    public static void lambda() {
//        (parameters) -> expression
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.forEach((Integer number) -> System.out.println(number));
        numbers.forEach(number -> System.out.println(number));
        List<String> names = Arrays.asList("John", "Mary", "Bob");
        names.forEach(System.out::println);
    }


}
